package cn.lyvust.first.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;

public class JwtUtil {

    /**
     * 过期时间一周
     */
    private static final long EXPIRE_TIME = 7*12*3600*1000;
    public static final int SALT_SIZE = 8;
    public static final int HASH_INTERATIONS = 1024;
    /**
     * 校验token是否正确
     * @param token 密钥
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verify(String token, String username, String secret) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("username", username)
                    .build();
            verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的指定KEY值信息
     */
    public static String get(String token,String key) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名,5min后过期
     * @param username 用户名
     * @param secret 用户的密码
     * @return 加密的token
     */
//    public static String sign(String uid,String username, String secret) {
//        Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
//        Algorithm algorithm = Algorithm.HMAC256(secret);
//        // 附带username信息
//        return JWT.create()
//                .withClaim("uid", uid)
//                .withClaim("username", username)
//                .withExpiresAt(date)
//                .sign(algorithm);
//    }

    public static String sign(String uid,String username, String secret) {
        Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        // 附带username信息
        return JWT.create()
                .withClaim("uid", uid)
                .withClaim("username", username)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    /**
     * 生成安全的密码，生成随机的16位salt并经过1024次 md5 hash
     */
    public static String entryptPassword(String plainPassword) {
        plainPassword= Encodes.unescapeHtml(plainPassword);
        byte[] salt = MD5EncryptUtil.generateSalt(SALT_SIZE);
        byte[] hashPassword = MD5EncryptUtil.md5(plainPassword.getBytes(), salt, HASH_INTERATIONS);
        return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
    }


    /**
     * 验证密码
     *
     * @param plainPassword
     *            明文密码
     * @param password
     *            密文密码
     * @return 验证成功返回true
     */
    public static boolean validatePassword(String plainPassword, String password) {
        byte[] salt = Encodes.decodeHex(password.substring(0, 16));
        byte[] hashPassword = MD5EncryptUtil.md5(plainPassword.getBytes(), salt,
                HASH_INTERATIONS);
        return password.equals(Encodes.encodeHex(salt)
                + Encodes.encodeHex(hashPassword));
    }
}
